/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sirtet.tetris.program;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import sirtet.ControlledPlayer;
import sirtet.Player;
import sirtet.gui.KeyboardPlayer;
import sirtet.netplay.Communicator;
import sirtet.netplay.SynchronizedPlayer;
import sirtet.netplay.server.BounceServer;
import sirtet.netplay.server.Receptionist;
import sirtet.tetris.BattlingTetrisBoard;
import sirtet.tetris.FallEnforcer;
import sirtet.tetris.RandomPieceProvider;
import sirtet.tetris.TetrisAction;
import sirtet.tetris.TetrisBoard;
import sirtet.tetris.gui.NextPiecePanel;
import sirtet.tetris.gui.TetrisGamePanel;
import sirtet.tetris.gui.fancy.FancyBoardPanel;

/**
 * A simple crappy demonstration about how to use BounceServer, KeyboardPlayer,
 * ControlledPlayer and BattlingTetrisBoard.
 * @author guangwei.zhu
 */
public class LocalBattlingTetris extends JFrame {

    private Receptionist gate;

    public LocalBattlingTetris() {
        // Initialize server side
        try {
            gate = new Receptionist(9462);
            gate.addHandler(new BounceServer(0));
            gate.beginWait();


            this.setLayout(new GridLayout(1, 2));

            // Next piece panel
            NextPiecePanel nextPiecePanel1 = new NextPiecePanel();
            nextPiecePanel1.setVisible(true);
            nextPiecePanel1.setPreferredSize(new Dimension(140, 0));

            // TetrisBoard and its panel
            BattlingTetrisBoard board1 = new BattlingTetrisBoard(20, 30);
            FancyBoardPanel boardPanel1 = new FancyBoardPanel(board1);
            TetrisGamePanel mainPanel1 = new TetrisGamePanel(boardPanel1, nextPiecePanel1);

            // Let NextPiecePanel know when to draw new pieces
            board1.addBoardListener(nextPiecePanel1);

            // New piece provider
            board1.setPieceProvider(new RandomPieceProvider());

            // KeyboardPlayer - keyboard input
            KeyboardPlayer player1 = new KeyboardPlayer("guangwei.zhu.alt", TetrisBoard.GAMETYPE);
            mainPanel1.setFocusable(false);
            player1.registerKeyCommand(KeyEvent.VK_S, TetrisAction.FALL);
            player1.registerKeyCommand(KeyEvent.VK_A, TetrisAction.LEFT);
            player1.registerKeyCommand(KeyEvent.VK_D, TetrisAction.RIGHT);
            player1.registerKeyCommand(KeyEvent.VK_W, TetrisAction.ROTATE);

            // Relate the KeyboardPlayer to this JForm
            this.addKeyListener(player1);

            Player player1N;
            // Add network layer
            player1N = new ControlledPlayer(player1, 200);
            board1.registerPlayer(player1N);


            // Next piece panel
            NextPiecePanel nextPiecePanel2 = new NextPiecePanel();
            nextPiecePanel2.setVisible(true);
            nextPiecePanel2.setPreferredSize(new Dimension(140, 0));

            // TetrisBoard and its panel
            BattlingTetrisBoard board2 = new BattlingTetrisBoard(20, 30);
            FancyBoardPanel boardPanel2 = new FancyBoardPanel(board2);
            TetrisGamePanel mainPanel2 = new TetrisGamePanel(boardPanel2, nextPiecePanel2);

            // Let NedataxtPiecePanel know when to draw new pieces
            board2.addBoardListener(nextPiecePanel2);

            // New piece provider
            board2.setPieceProvider(new RandomPieceProvider());

            // KeyboardPlayer - keyboard input
            KeyboardPlayer player2 = new KeyboardPlayer("guangwei.zhu", TetrisBoard.GAMETYPE);
            mainPanel2.setFocusable(false);
            player2.registerKeyCommand(KeyEvent.VK_DOWN, TetrisAction.FALL);
            player2.registerKeyCommand(KeyEvent.VK_LEFT, TetrisAction.LEFT);
            player2.registerKeyCommand(KeyEvent.VK_RIGHT, TetrisAction.RIGHT);
            player2.registerKeyCommand(KeyEvent.VK_UP, TetrisAction.ROTATE);

            // Relate the KeyboardPlayer to this JForm
            this.addKeyListener(player2);

            SynchronizedPlayer player2N;
            // Add network layer
            player2N = new SynchronizedPlayer(player2, new Communicator("localhost", 9462));
            player2N.getCommunicator().activate();
            board2.registerPlayer(player2N);

            // Play against each other
            board1.addAttackTarget(board2);
            board2.addAttackTarget(board1);

            // Register a fall enforcer
            board1.registerPlayer(new FallEnforcer(1000));
            board2.registerPlayer(new FallEnforcer(500));

            player1N.setReady(true);
            player2N.setReady(true);
            // Start the board game
            while (!player1N.ready() || !player2N.ready()) {
            }
            board1.start();
            board2.start();

            this.add(mainPanel1);
            this.add(mainPanel2);

            this.addWindowListener(new WindowAdapter() {

                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }

            });

        } catch (Exception ex) {
            System.err.println(ex);
            System.exit(-1);
        }
    }

    public static void main(String[] args) {
        LocalBattlingTetris window = new LocalBattlingTetris();
        window.setVisible(true);
        window.setSize(1250, 700);
    }
}
